﻿#include <iostream>
#include "StructTest.h"
#include "MyEnum.h"
#include <string>
#include <string_view>


//打印枚举
constexpr std::string_view getColor(Color color) // C++17
{
	switch (color)
	{
	case black: return "black";
	case red:   return "red";
	case blue:  return "blue";
	case green:  return "green";
	default:    return "???";
	}
}


// 设定 operator<< 如何打印 Color
// 现在可能看起来有点神奇，后续进行介绍
// std::ostream 是 std::cout 的类型
// 返回值与参数都是引用 (避免制作副本)!
std::ostream& operator<<(std::ostream& out, Color color)
{
	switch (color)
	{
	case black: return out << "black";
	case red:   return out << "red";
	case blue:  return out << "blue";
	case green:  return out << "green";
	default:    return out << "???";
	}
}


std::ostream& operator<<(std::ostream& out, Color2 color)
{
	switch (color)
	{
	case black2: return out << "black2";
	case red2:   return out << "red2";
	case blue2:  return out << "blue2";
	default:    return out << "???";
	}
}


int main()
{
	std::cout << "Hello World!\n";

	//在方法中使用结构体
	MyStruct mt{ 2,4 };
	std::cout << mt.A << "\n";
	std::cout << mt.B << "\n";


	// 定义Color类型的一些变量
	Color apple{ red };   // 苹果是红色
	Color shirt{ green }; // 衬衫是绿色
	Color cup{ blue };    // 杯子是蓝色


	std::cout << apple << "\n";
	std::cout << shirt << "\n";
	std::cout << cup << "\n";


	//枚举配合switch使用
	switch (apple)
	{
	case red:
		break;
	case green:
		break;
	case blue:
		break;
	default:
		break;
	}

	//改变枚举
	apple = green;
	shirt = red;
	cup = black;

	//使用自定义方法打印枚举
	std::cout << getColor(apple) << "\n";
	std::cout << getColor(shirt) << "\n";
	std::cout << getColor(cup) << "\n";


	//设定运算符«以打印枚举数(上面自定义的操作符重载方法)
	std::cout << apple << "\n";
	std::cout << shirt << "\n";
	std::cout << cup << "\n";

	//打印有类型限定的枚举
	Color2 a = black2;
	Color2 b = red2;
	Color2 c = blue2;
	std::cout << a << "\n";
	std::cout << b << "\n";
	std::cout << c << "\n";

	//整数到枚举之间的转换
	Color cr = static_cast<Color>(1);
	std::cout << "数字1转换后的枚举：" << cr << "\n";


	//指定底层类型,则编译器将允许您使用整数值来列表初始化非限定作用域枚举
	Pet pet1{ 2 }; // ok: 使用列表初始化
	//Pet pet2(2);   // 编译错误: 不能使用整数做直接初始化
	//Pet pet3 = 2;   // 编译错误: 不能使用整数做复制初始化
	//pet1 = 3;       // 编译错误: 不能使用整数赋值


	//使用限定作用域枚举
	Fruit f = Fruit::apple;
	std::string_view sv = f == Fruit::apple ? "apple" : "unapple";
	std::cout<<"非限定作用域枚举：" << sv << "\n";





}
